/*
Copyright 2005, 2006, 2007 Dennis van Weeren

This file is part of Minimig

Minimig is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

Minimig is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

This is the Minimig OSD (on-screen-display) handler.

29-12-2006	- created
30-12-2006	- improved and simplified

-- JB --
2009-02-03	- added arrows characters (codes 240-243)
			- added full keyboard support
			- added configuration functions for floppy, scanline and chipset
*/

#include <pic18.h>
#include "osd.h"
#include "hardware.h"

/*character font*/
const unsigned char charfont[256][5]=
{
        0x00,0x7F,0x40,0x7F,0x00,       // 0   [0x00]
        0x00,0x7F,0x60,0x7F,0x00,       // 1   [0x01]
        0x00,0x7F,0x70,0x7F,0x00,       // 2   [0x02]
        0x00,0x7F,0x78,0x7F,0x00,       // 3   [0x03]
        0x00,0x7F,0x7C,0x7F,0x00,       // 4   [0x04]
        0x00,0x7F,0x7E,0x7F,0x00,       // 5   [0x05]
        0x00,0x7F,0x7F,0x7F,0x00,       // 6   [0x06]
        0x0C,0x0F,0x60,0x7C,0x04,       // 7   [0x07]
        0x0C,0x21,0x1E,0x40,0x3F,       // 8   [0x08]
        0x19,0x15,0x73,0x15,0x19,       // 9   [0x09]
        0x71,0x28,0x71,0x32,0x49,       // 10  [0x0A]
        0x7A,0x48,0x32,0x30,0x4A,       // 11  [0x0B]
        0x2E,0x31,0x01,0x31,0x2E,       // 12  [0x0C]
        0x7D,0x00,0x78,0x48,0x7F,       // 13  [0x0D]
        0x1F,0x1F,0x1B,0x1F,0x1F,       // 14  [0x0E]
        0x1C,0x22,0x22,0x14,0x14,       // 15  [0x0F]
        0x00,0x7F,0x3E,0x1C,0x08,       // 16  [0x10]
        0x08,0x1C,0x3E,0x7F,0x00,       // 17  [0x11]
        0x30,0x7F,0x7C,0x6F,0x30,       // 18  [0x12]
        0x06,0x0F,0x7E,0x0F,0x06,       // 19  [0x13]
        0x44,0x66,0x77,0x66,0x44,       // 20  [0x14]
        0x11,0x33,0x77,0x33,0x11,       // 21  [0x15]
        0x1C,0x3E,0x3E,0x3E,0x1C,       // 22  [0x16]
        0x10,0x38,0x54,0x10,0x1F,       // 23  [0x17]
        0x04,0x02,0x7F,0x02,0x04,       // 24  [0x18]
        0x10,0x20,0x7F,0x20,0x10,       // 25  [0x19]
        0x08,0x08,0x2A,0x1C,0x08,       // 26  [0x1A]
        0x08,0x1C,0x2A,0x08,0x08,       // 27  [0x1B]
        0x40,0x44,0x4A,0x51,0x40,       // 28  [0x1C]
        0x40,0x51,0x4A,0x44,0x40,       // 29  [0x1D]
        0x20,0x38,0x3E,0x38,0x20,       // 30  [0x1E]
        0x02,0x0E,0x3E,0x0E,0x02,       // 31  [0x1F]
        0x00,0x00,0x00,0x00,0x00,       // 32  [0x20] ' '
        0x00,0x00,0x5F,0x00,0x00,       // 33  [0x21] '!'
        0x00,0x07,0x00,0x07,0x00,       // 34  [0x22] '"'
        0x14,0x7F,0x14,0x7F,0x14,       // 35  [0x23] '#'
        0x24,0x2A,0x7F,0x2A,0x12,       // 36  [0x24] '$'
        0x23,0x13,0x08,0x64,0x62,       // 37  [0x25] '%'
        0x36,0x49,0x55,0x22,0x50,       // 38  [0x26] '&'
        0x00,0x00,0x05,0x03,0x00,       // 39  [0x27] '''
        0x00,0x1C,0x22,0x41,0x00,       // 40  [0x28] '('
        0x00,0x41,0x22,0x1C,0x00,       // 41  [0x29] ')'
        0x14,0x08,0x3E,0x08,0x14,       // 42  [0x2A] '*'
        0x08,0x08,0x3E,0x08,0x08,       // 43  [0x2B] '+'
        0x00,0x50,0x30,0x00,0x00,       // 44  [0x2C] ','
        0x08,0x08,0x08,0x08,0x08,       // 45  [0x2D] '-'
        0x00,0x60,0x60,0x00,0x00,       // 46  [0x2E] '.'
        0x20,0x10,0x08,0x04,0x02,       // 47  [0x2F] '/'
        0x3E,0x51,0x49,0x45,0x3E,       // 48  [0x30] '0'
        0x00,0x42,0x7F,0x40,0x00,       // 49  [0x31] '1'
        0x42,0x61,0x51,0x49,0x46,       // 50  [0x32] '2'
        0x21,0x41,0x45,0x4B,0x31,       // 51  [0x33] '3'
        0x18,0x14,0x12,0x7F,0x10,       // 52  [0x34] '4'
        0x27,0x45,0x45,0x45,0x39,       // 53  [0x35] '5'
        0x3C,0x4A,0x49,0x49,0x30,       // 54  [0x36] '6'
        0x03,0x01,0x71,0x09,0x07,       // 55  [0x37] '7'
        0x36,0x49,0x49,0x49,0x36,       // 56  [0x38] '8'
        0x06,0x49,0x49,0x29,0x1E,       // 57  [0x39] '9'
        0x00,0x66,0x66,0x00,0x00,       // 58  [0x3A] ':'
        0x00,0x56,0x36,0x00,0x00,       // 59  [0x3B] ';'
        0x08,0x14,0x22,0x41,0x00,       // 60  [0x3C] '<'
        0x14,0x14,0x14,0x14,0x14,       // 61  [0x3D] '='
        0x00,0x41,0x22,0x14,0x08,       // 62  [0x3E] '>'
        0x02,0x01,0x51,0x09,0x06,       // 63  [0x3F] '?'
        0x32,0x49,0x79,0x41,0x3E,       // 64  [0x40] '@'
        0x7C,0x12,0x11,0x12,0x7C,       // 65  [0x41] 'A'
        0x7F,0x49,0x49,0x49,0x36,       // 66  [0x42] 'B'
        0x3E,0x41,0x41,0x41,0x22,       // 67  [0x43] 'C'
        0x7F,0x41,0x41,0x22,0x1C,       // 68  [0x44] 'D'
        0x7F,0x49,0x49,0x49,0x41,       // 69  [0x45] 'E'
        0x7F,0x09,0x09,0x09,0x01,       // 70  [0x46] 'F'
        0x3E,0x41,0x49,0x49,0x7A,       // 71  [0x47] 'G'
        0x7F,0x08,0x08,0x08,0x7F,       // 72  [0x48] 'H'
        0x00,0x41,0x7F,0x41,0x00,       // 73  [0x49] 'I'
        0x20,0x40,0x41,0x3F,0x01,       // 74  [0x4A] 'J'
        0x7F,0x08,0x14,0x22,0x41,       // 75  [0x4B] 'K'
        0x7F,0x40,0x40,0x40,0x40,       // 76  [0x4C] 'L'
        0x7F,0x02,0x0C,0x02,0x7F,       // 77  [0x4D] 'M'
        0x7F,0x04,0x08,0x10,0x7F,       // 78  [0x4E] 'N'
        0x3E,0x41,0x41,0x41,0x3E,       // 79  [0x4F] 'O'
        0x7F,0x09,0x09,0x09,0x06,       // 80  [0x50] 'P'
        0x3E,0x41,0x51,0x21,0x5E,       // 81  [0x51] 'Q'
        0x7F,0x09,0x19,0x29,0x46,       // 82  [0x52] 'R'
        0x26,0x49,0x49,0x49,0x32,       // 83  [0x53] 'S'
        0x01,0x01,0x7F,0x01,0x01,       // 84  [0x54] 'T'
        0x3F,0x40,0x40,0x40,0x3F,       // 85  [0x55] 'U'
        0x1F,0x20,0x40,0x20,0x1F,       // 86  [0x56] 'V'
        0x7F,0x20,0x18,0x20,0x7F,       // 87  [0x57] 'W'
        0x63,0x14,0x08,0x14,0x63,       // 88  [0x58] 'X'
        0x07,0x08,0x70,0x08,0x07,       // 89  [0x59] 'Y'
        0x61,0x51,0x49,0x45,0x43,       // 90  [0x5A] 'Z'
        0x00,0x7F,0x41,0x41,0x00,       // 91  [0x5B] '['
        0x02,0x04,0x08,0x10,0x20,       // 92  [0x5C] '\'
        0x00,0x41,0x41,0x7F,0x00,       // 93  [0x5D] ']'
        0x04,0x02,0x01,0x02,0x04,       // 94  [0x5E] '^'
        0x40,0x40,0x40,0x40,0x40,       // 95  [0x5F] '_'
        0x00,0x01,0x02,0x04,0x00,       // 96  [0x60] '`'
        0x20,0x54,0x54,0x54,0x78,       // 97  [0x61] 'a'
        0x7F,0x48,0x44,0x44,0x38,       // 98  [0x62] 'b'
        0x38,0x44,0x44,0x44,0x20,       // 99  [0x63] 'c'
        0x38,0x44,0x44,0x48,0x7F,       // 100 [0x64] 'd'
        0x38,0x54,0x54,0x54,0x18,       // 101 [0x65] 'e'
        0x08,0x7E,0x09,0x01,0x02,       // 102 [0x66] 'f'
        0x08,0x54,0x54,0x54,0x3C,       // 103 [0x67] 'g'
        0x7F,0x08,0x04,0x04,0x78,       // 104 [0x68] 'h'
        0x00,0x48,0x7D,0x40,0x00,       // 105 [0x69] 'i'
        0x20,0x40,0x44,0x3D,0x00,       // 106 [0x6A] 'j'
        0x00,0x7F,0x10,0x28,0x44,       // 107 [0x6B] 'k'
        0x00,0x41,0x7F,0x40,0x00,       // 108 [0x6C] 'l'
        0x7C,0x04,0x78,0x04,0x7C,       // 109 [0x6D] 'm'
        0x7C,0x08,0x04,0x04,0x78,       // 110 [0x6E] 'n'
        0x38,0x44,0x44,0x44,0x38,       // 111 [0x6F] 'o'
        0x7C,0x14,0x14,0x14,0x08,       // 112 [0x70] 'p'
        0x04,0x0A,0x0A,0x0C,0x7E,       // 113 [0x71] 'q'
        0x7C,0x08,0x04,0x04,0x08,       // 114 [0x72] 'r'
        0x48,0x54,0x54,0x54,0x20,       // 115 [0x73] 's'
        0x04,0x3F,0x44,0x40,0x20,       // 116 [0x74] 't'
        0x3C,0x40,0x40,0x20,0x7C,       // 117 [0x75] 'u'
        0x1C,0x20,0x40,0x20,0x1C,       // 118 [0x76] 'v'
        0x3C,0x40,0x30,0x40,0x3C,       // 119 [0x77] 'w'
        0x44,0x28,0x10,0x28,0x44,       // 120 [0x78] 'x'
        0x0C,0x50,0x50,0x50,0x3C,       // 121 [0x79] 'y'
        0x44,0x64,0x54,0x4C,0x44,       // 122 [0x7A] 'z'
        0x00,0x08,0x36,0x41,0x00,       // 123 [0x7B] '{'
        0x00,0x00,0x7F,0x00,0x00,       // 124 [0x7C] '|'
        0x00,0x41,0x36,0x08,0x00,       // 125 [0x7D] '}'
        0x02,0x01,0x02,0x04,0x02,       // 126 [0x7E] '~'
        0x78,0x44,0x42,0x44,0x78,       // 127 [0x7F]
        0x00,0x00,0x00,0x00,0x00,       // 128 [0x80]
        0x7F,0x7F,0x19,0x7F,0x7F,       // 129 [0x81]
        0x7F,0x7F,0x6D,0x7F,0x3B,       // 130 [0x82]
        0x3F,0x7F,0x61,0x61,0x61,       // 131 [0x83]
        0x7F,0x7F,0x61,0x7F,0x3F,       // 132 [0x84]
        0x7F,0x7F,0x6D,0x6D,0x61,       // 133 [0x85]
        0x7F,0x7F,0x0D,0x0D,0x01,       // 134 [0x86]
        0x3F,0x7F,0x69,0x7B,0x3B,       // 135 [0x87]
        0x7F,0x7F,0x0C,0x7F,0x7F,       // 136 [0x88]
        0x00,0x7F,0x7F,0x7F,0x00,       // 137 [0x89]
        0x30,0x70,0x60,0x7F,0x3F,       // 138 [0x8A]
        0x7F,0x7F,0x1E,0x7B,0x71,       // 139 [0x8B]
        0x7F,0x7F,0x60,0x60,0x60,       // 140 [0x8C]
        0x7F,0x03,0x0E,0x03,0x7F,       // 141 [0x8D]
        0x7F,0x1F,0x3F,0x7E,0x7F,       // 142 [0x8E]
        0x3F,0x7F,0x61,0x7F,0x3F,       // 143 [0x8F]
        0x7F,0x7F,0x19,0x1F,0x0F,       // 144 [0x90]
        0x3F,0x7F,0x71,0x3F,0x5F,       // 145 [0x91]
        0x7F,0x7F,0x1D,0x77,0x63,       // 146 [0x92]
        0x67,0x6F,0x6D,0x7D,0x39,       // 147 [0x93]
        0x01,0x7F,0x7F,0x7F,0x01,       // 148 [0x94]
        0x3F,0x7F,0x60,0x7F,0x3F,       // 149 [0x95]
        0x1F,0x3F,0x70,0x3F,0x1F,       // 150 [0x96]
        0x7F,0x70,0x1C,0x70,0x7F,       // 151 [0x97]
        0x63,0x7F,0x1C,0x7F,0x63,       // 152 [0x98]
        0x07,0x0F,0x78,0x0F,0x07,       // 153 [0x99]
        0x71,0x79,0x6D,0x67,0x63,       // 154 [0x9A]
        0x00,0x00,0x00,0x00,0x00,       // 155 [0x9B]
        0x00,0x00,0x00,0x00,0x00,       // 156 [0x9C]
        0x00,0x00,0x00,0x00,0x00,       // 157 [0x9D]
        0x00,0x00,0x00,0x00,0x00,       // 158 [0x9E]
        0x00,0x00,0x00,0x00,0x00,       // 159 [0x9F]
        0x00,0x00,0x00,0x00,0x00,       // 160 [0xA0]
        0x00,0x00,0x00,0x00,0x00,       // 161 [0xA1]
        0x00,0x00,0x00,0x00,0x00,       // 162 [0xA2]
        0x00,0x00,0x00,0x00,0x00,       // 163 [0xA3]
        0x00,0x00,0x00,0x00,0x00,       // 164 [0xA4]
        0x00,0x00,0x00,0x00,0x00,       // 165 [0xA5]
        0x00,0x00,0x00,0x00,0x00,       // 166 [0xA6]
        0x00,0x00,0x00,0x00,0x00,       // 167 [0xA7]
        0x00,0x00,0x00,0x00,0x00,       // 168 [0xA8]
        0x00,0x00,0x00,0x00,0x00,       // 169 [0xA9]
        0x00,0x00,0x00,0x00,0x00,       // 170 [0xAA]
        0x00,0x00,0x00,0x00,0x00,       // 171 [0xAB]
        0x00,0x00,0x00,0x00,0x00,       // 172 [0xAC]
        0x00,0x00,0x00,0x00,0x00,       // 173 [0xAD]
        0x00,0x00,0x00,0x00,0x00,       // 174 [0xAE]
        0x00,0x00,0x00,0x00,0x00,       // 175 [0xAF]
        0x00,0x00,0x00,0x00,0x00,       // 176 [0xB0]
        0x00,0x00,0x00,0x00,0x00,       // 177 [0xB1]
        0x00,0x00,0x00,0x00,0x00,       // 178 [0xB2]
        0x00,0x00,0x00,0x00,0x00,       // 179 [0xB3]
        0x00,0x00,0x00,0x00,0x00,       // 180 [0xB4]
        0x00,0x00,0x00,0x00,0x00,       // 181 [0xB5]
        0x00,0x00,0x00,0x00,0x00,       // 182 [0xB6]
        0x00,0x00,0x00,0x00,0x00,       // 183 [0xB7]
        0x00,0x00,0x00,0x00,0x00,       // 184 [0xB8]
        0x00,0x00,0x00,0x00,0x00,       // 185 [0xB9]
        0x00,0x00,0x00,0x00,0x00,       // 186 [0xBA]
        0x00,0x00,0x00,0x00,0x00,       // 187 [0xBB]
        0x00,0x00,0x00,0x00,0x00,       // 188 [0xBC]
        0x00,0x00,0x00,0x00,0x00,       // 189 [0xBD]
        0x00,0x00,0x00,0x00,0x00,       // 190 [0xBE]
        0x00,0x00,0x00,0x00,0x00,       // 191 [0xBF]
        0x00,0x00,0x00,0x00,0x00,       // 192 [0xC0]
        0x00,0x00,0x00,0x00,0x00,       // 193 [0xC1]
        0x00,0x00,0x00,0x00,0x00,       // 194 [0xC2]
        0x00,0x00,0x00,0x00,0x00,       // 195 [0xC3]
        0x00,0x00,0x00,0x00,0x00,       // 196 [0xC4]
        0x00,0x00,0x00,0x00,0x00,       // 197 [0xC5]
        0x00,0x00,0x00,0x00,0x00,       // 198 [0xC6]
        0x00,0x00,0x00,0x00,0x00,       // 199 [0xC7]
        0x00,0x00,0x00,0x00,0x00,       // 200 [0xC8]
        0x00,0x00,0x00,0x00,0x00,       // 201 [0xC9]
        0x00,0x00,0x00,0x00,0x00,       // 202 [0xCA]
        0x00,0x00,0x00,0x00,0x00,       // 203 [0xCB]
        0x00,0x00,0x00,0x00,0x00,       // 204 [0xCC]
        0x00,0x00,0x00,0x00,0x00,       // 205 [0xCD]
        0x00,0x00,0x00,0x00,0x00,       // 206 [0xCE]
        0x00,0x00,0x00,0x00,0x00,       // 207 [0xCF]
        0x00,0x00,0x00,0x00,0x00,       // 208 [0xD0]
        0x00,0x00,0x00,0x00,0x00,       // 209 [0xD1]
        0x00,0x00,0x00,0x00,0x00,       // 210 [0xD2]
        0x00,0x00,0x00,0x00,0x00,       // 211 [0xD3]
        0x00,0x00,0x00,0x00,0x00,       // 212 [0xD4]
        0x00,0x00,0x00,0x00,0x00,       // 213 [0xD5]
        0x00,0x00,0x00,0x00,0x00,       // 214 [0xD6]
        0x00,0x00,0x00,0x00,0x00,       // 215 [0xD7]
        0x00,0x00,0x00,0x00,0x00,       // 216 [0xD8]
        0x00,0x00,0x00,0x00,0x00,       // 217 [0xD9]
        0x00,0x00,0x00,0x00,0x00,       // 218 [0xDA]
        0x00,0x00,0x00,0x00,0x00,       // 219 [0xDB]
        0x00,0x00,0x00,0x00,0x00,       // 220 [0xDC]
        0x00,0x00,0x00,0x00,0x00,       // 221 [0xDD]
        0x00,0x00,0x00,0x00,0x00,       // 222 [0xDE]
        0x00,0x00,0x00,0x00,0x00,       // 223 [0xDF]
        0x00,0x00,0x00,0x00,0x00,       // 224 [0xE0]
        0x00,0x00,0x00,0x00,0x00,       // 225 [0xE1]
        0x00,0x00,0x00,0x00,0x00,       // 226 [0xE2]
        0x00,0x00,0x00,0x00,0x00,       // 227 [0xE3]
        0x00,0x00,0x00,0x00,0x00,       // 228 [0xE4]
        0x00,0x00,0x00,0x00,0x00,       // 229 [0xE5]
        0x00,0x00,0x00,0x00,0x00,       // 230 [0xE6]
        0x00,0x00,0x00,0x00,0x00,       // 231 [0xE7]
        0x00,0x00,0x00,0x00,0x00,       // 232 [0xE8]
        0x02,0x2A,0x28,0x0A,0x22,       // 233 [0xE9]
        0x00,0x00,0x00,0x00,0x00,       // 234 [0xEA]
        0x00,0x00,0x00,0x00,0x00,       // 235 [0xEB]
        0x08,0x11,0x08,0x11,0x08,       // 236 [0xEC]
        0x08,0x11,0x10,0x11,0x08,       // 237 [0xED]
        0x10,0x11,0x10,0x11,0x10,       // 238 [0xEE]
        0x20,0x11,0x10,0x11,0x20,       // 239 [0xEF]
        0x08,0x1C,0x3E,0x08,0x08,       // 240 [0xF0] arrow left
        0x08,0x08,0x3E,0x1C,0x08,       // 241 [0xF1] arrow right
        0x08,0x0C,0x3E,0x0C,0x08,       // 242 [0xF2] arrow up
        0x08,0x18,0x3E,0x18,0x08,       // 243 [0xF3] arrow down
        0x00,0x00,0x00,0x00,0x00,       // 244 [0xF4]
        0x00,0x00,0x00,0x00,0x00,       // 245 [0xF5]
        0x00,0x00,0x00,0x00,0x00,       // 246 [0xF6]
        0x00,0x00,0x00,0x00,0x00,       // 247 [0xF7]
        0x00,0x00,0x00,0x00,0x00,       // 248 [0xF8]
        0x7F,0x3D,0x7F,0x3D,0x7F,       // 249 [0xF9]
        0x7F,0x3D,0x7F,0x3D,0x7F,       // 250 [0xFA]
        0x7E,0x3C,0x7E,0x3C,0x7E,       // 251 [0xFB]
        0x7C,0x3C,0x7C,0x3C,0x7C,       // 252 [0xFC]
        0x78,0x38,0x78,0x38,0x78,       // 253 [0xFD]
        0x70,0x30,0x70,0x30,0x70,       // 254 [0xFE]
        0x60,0x20,0x60,0x20,0x60        // 255 [0xFF]
};

//Amiga keyboard codes to ASCII convertion table
const char keycode_table[128] =
{
	  0,'1','2','3','4','5','6','7','8','9','0',  0,  0,  0,  0,  0,
	'Q','W','E','R','T','Y','U','I','O','P',  0,  0,  0,  0,  0,  0,
	'A','S','D','F','G','H','J','K','L',  0,  0,  0,  0,  0,  0,  0,
	  0,'Z','X','C','V','B','N','M',  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
	  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0
};

/*some constants*/
#define OSDNLINE		8			/*number of lines of OSD*/
#define	OSDLINELEN		128			/*single line length in bytes*/
#define OSDCMDREAD      0x00        //OSD read controller/key status
#define OSDCMDWRITE     0x20        //OSD write video data command
#define OSDCMDENABLE    0x60        //OSD enable command
#define OSDCMDDISABLE   0x40        //OSD disable command
#define OSDCMDRST       0x80        //OSD reset command
#define OSDCMDCFGSCL    0xA0        //OSD settings: scanline effect
#define OSDCMDENAHDD    0xB0        //OSD enable HDD command
#define OSDCMDCFGFLP    0xC0        //OSD settings: floppy config
#define OSDCMDCFGCPU    0xD0        //OSD settings: cpu config
#define OSDCMDCFGFLT    0xE0        //OSD settings: filter
#define OSDCMDCFGMEM    0xF0        //OSD settings: memory config

#define REPEATDELAY		50			/*repeat delay in 10ms units*/
#define REPEATRATE		2			/*repeat rate in 10ms units*/


/*write a null-terminated string <s> to the OSD buffer starting at line <n>*/
void OsdWrite(unsigned char n,const unsigned char *s,char invert)
{
	unsigned char b;
	const unsigned char *p;

	/*select OSD SPI device*/
	EnableOsd();

	/*select buffer and line to write to*/
	if (invert)
		SPI(OSDCMDWRITE|0x10|n);
	else
		SPI(OSDCMDWRITE|n);

	/*send all characters in string to OSD*/
	while(1)
	{
		b=*(s++);

		if (b==0)/*end of string*/
			break;
		else if (b==0x0d || b==0x0a)//cariage return / linefeed, go to next line
		{
			/*increment line counter*/
			if(++n>=OSDNLINE)
				n=0;
			/*send new line number to OSD*/
			DisableOsd();
			EnableOsd();
			SPI(OSDCMDWRITE|n);
		}
		else/*normal character*/
		{
			SPI(0x00);
			SPI(0x00);
			p=&charfont[b][0];
			SPI(*p);
			SPI(*p++);
			SPI(*p);
			SPI(*p++);
			SPI(*p);
			SPI(*p++);
			SPI(*p);
			SPI(*p++);
			SPI(*p);
			SPI(*p++);
		}
	}
	/*deselect OSD SPI device*/
	DisableOsd();
}

/*clear buffer <c>*/
void OsdClear(void)
{
	unsigned short n;

	/*select OSD SPI device*/
	EnableOsd();

	/*select buffer to write to*/
	SPI(OSDCMDWRITE|0x18);

	/*clear buffer*/
	for(n=0;n<(2*OSDLINELEN*OSDNLINE);n++)
		SPI(0x00);

	/*deselect OSD SPI device*/
	DisableOsd();
}

/*enable displaying of OSD*/
void OsdEnable(void)
{
	/*send command*/
	EnableOsd();
	SPI(OSDCMDENABLE);
	DisableOsd();
}

/*disable displaying of OSD*/
void OsdDisable(void)
{
	/*send command*/
	EnableOsd();
	SPI(OSDCMDDISABLE);
	DisableOsd();
}

void OsdReset(unsigned char boot)
{
	EnableOsd();
	SPI(OSDCMDRST | (boot&0x01));
	DisableOsd();
}

void ConfigFilter(unsigned char lores, unsigned char hires)
{
	EnableOsd();
	SPI(OSDCMDCFGFLT | ((hires&0x03)<<2) | (lores&0x03));
	DisableOsd();
}

void ConfigMemory(unsigned char memory)
{
	EnableOsd();
	SPI(OSDCMDCFGMEM | (memory&0x0F));
	DisableOsd();
}

void ConfigChipset(unsigned char chipset)
{
	EnableOsd();
	SPI(OSDCMDCFGCPU | (chipset&0x0F));
	DisableOsd();
}

void ConfigFloppy(unsigned char drives, unsigned char speed)
{
	EnableOsd();
	SPI(OSDCMDCFGFLP | ((drives&0x03)<<2) | (speed&0x03));
	DisableOsd();
}

void ConfigScanline(unsigned char scanline)
{
	EnableOsd();
	SPI(OSDCMDCFGSCL | (scanline&0x0F));
	DisableOsd();
}

/*get key status*/
unsigned char OsdGetCtrl(void)
{
	static unsigned char c2;
	static unsigned long repeat;
	unsigned char c1,c;

	/*send command and get current ctrl status*/
	EnableOsd();
	c1 = SPI(OSDCMDREAD);
	DisableOsd();

	/*add front menu button*/
	if (CheckButton())
		c1 = KEY_MENU;

	/*generate normal "key-pressed" event*/
	c = 0;
	if (c1!=c2)
		c = c1;

	c2 = c1;

	/*generate repeat "key-pressed" events
	do not for menu button*/

	if (!c1)
		repeat = GetTimer(REPEATDELAY);
	else if (CheckTimer(repeat))
	{
		repeat = GetTimer(REPEATRATE);
		if (c1==KEY_UP || c1==KEY_DOWN || GetASCIIKey(c1))
			c = c1;
	}
	/*return events*/
	return(c);
}

unsigned char GetASCIIKey(unsigned char keycode)
{
	return keycode&0x80 ? 0 : keycode_table[keycode&0x7F];
}


